import Konva from "konva";
import { ref } from 'vue'
import { message } from "@/utils/message";

// 全局变量
var stage: any, layer: any, wheelScale: number, scale: number = 1.1, lineWidth: number = 1, initScale = 1, tooltip
// 站点类型
var stationType = new Map([
  [0,'rgba(255, 120, 39, 1)'],
  [1,'rgba(47, 107, 163, 1)'],
  [2,'rgba(203, 65, 31, 1)'],
  [3,'rgba(123, 32, 201, 1)']
])

export function initKonvaStage(container, refs, data) {
  stage = new Konva.Stage({
    container,
    width: refs.value.clientWidth,
    height: refs.value.clientHeight,
    draggable: true
  });
  layer = new Konva.Layer();

  // 绘制地图
  toDrawMap(data)

  // 滚动缩放
  mousewheel()

  stage.scale({ x: 1, y: -1 });
  stage.position({ x: 0, y: refs.value.clientHeight });

  stage.add(layer);

  // 缩放居中
  toCenter()

  tooltip = new Konva.Label({
    opacity: 0.75,
    visible: false,
    listening: false,
    scaleY: -1
  });

  tooltip.add(
    new Konva.Tag({
      fill: 'black',
      pointerDirection: 'down',
      pointerWidth: lineWidth,
      pointerHeight: lineWidth,
      lineJoin: 'round',
      shadowColor: 'black',
      shadowBlur: lineWidth,
      shadowOffsetX: lineWidth,
      shadowOffsetY: lineWidth,
      shadowOpacity: 0.5
    })
  );

  tooltip.add(
    new Konva.Text({
      text: '',
      fontFamily: 'Calibri',
      fontSize: 5,
      padding: 2,
      fill: 'white'
    })
  );

  layer.add(tooltip);

}


// 缩放居中
function toCenter() {
  // 获取绘制内容的边界框
  const boxRect = layer.getClientRect();

  // 计算缩放比例
  initScale = Math.max((stage.width()) / boxRect.width, (stage.height()) / boxRect.height);

  const shapes = layer.getChildren()

  // 缩放图形层
  shapes.forEach(v => {
    const { name } = v.attrs
    if (name === 'station') {
      v.x(v.x() * initScale)
      v.y(v.y() * initScale)
    } else if (name === 'road') {
      let points = v.points().map(v => {
        return v * initScale
      })
      v.points(points)
    } else if (name === 'bezier') {
      v.attrs.sceneFunc = function(ctx, shape) {
        let {moveTo,curveTo} = shape.attrs

        ctx.beginPath();
        ctx.moveTo(moveTo[0] * initScale,moveTo[1] * initScale);
        ctx.bezierCurveTo(curveTo[0] * initScale,curveTo[1] * initScale,curveTo[2] * initScale,curveTo[3] * initScale,curveTo[4] * initScale,curveTo[5] * initScale);
        ctx.setAttr('strokeStyle', '#ffffff');
        ctx.setAttr('lineWidth', 2);
        ctx.stroke();
      }
    }
  })

  // 重新计算边界
  const nextRect = layer.getClientRect();
  stage.offset({
    x: nextRect.x - (stage.width() - nextRect.width) / 2,
    y: -nextRect.y + (stage.height() - nextRect.height) / 2
  })
  
}

// 地图绘制
function toDrawMap(data) {
  data.roads.map(v => { 
    if(v.linetype === 0) return LINE(v);  // 直线
    if(v.linetype === 1) return bezier(v) // 凹弧线
    if(v.linetype === 2) return bezier(v) // 凸弧线
    if(v.linetype === 3) return bezier(v) // 贝塞尔
  })
  data.stations.map(v => { return CIRCLE(v) })
}

// 贝塞尔曲线
function bezier(val){
  let {points,assistList} = val
  var rect = new Konva.Shape({
    name:'bezier',
    moveTo:[points[0], points[1]],
    curveTo:[assistList[0].x,assistList[0].y,assistList[1].x,assistList[1].y, points[2], points[3]],
    sceneFunc: function (ctx, shape) {
      let {moveTo,curveTo} = shape.attrs
      ctx.beginPath();
      ctx.moveTo(moveTo[0],moveTo[1]);
      ctx.bezierCurveTo(curveTo[0],curveTo[1],curveTo[2],curveTo[3],curveTo[4],curveTo[5]);
      ctx.setAttr('strokeStyle', '#ffffff');
      ctx.setAttr('lineWidth', 2);
      ctx.stroke();
    }
  });
  layer.add(rect)
}

// 直线
function LINE(val) {
  var line = new Konva.Line({
    name: 'road',
    points: val.points,
    stroke: '#ffffff',
    strokeWidth: lineWidth*2,
    lineJoin: 'round',
  });

  line.shadowColor("#93f8fb"); // 设置阴影颜色
  line.shadowBlur(5);          // 设置阴影模糊度
  line.shadowOffsetX(0);       // 设置阴影 X 偏移量
  line.shadowOffsetY(0);       // 设置阴影 Y 偏移量
  line.shadowEnabled(true);    // 启用阴影

  layer.add(line);
}

// 曲线
function ARC(entitie) {
  let { center, radius, endAngle, startAngle, angleLength } = entitie

  const arc = new Konva.Shape({
    name: "arc",
    strokeWidth: lineWidth,
    sceneFunc(ctx, shape) {
      ctx.beginPath();
      ctx.arc(
        center.x,
        center.y,
        radius,
        startAngle,
        endAngle,
        false
      );//圆心，半径，开始和结束角度，false为逆时针
      //@ts-ignore
      ctx.strokeStyle = color;
      ctx.lineWidth = shape.attrs.strokeWidth
      ctx.stroke();
    }
  });

  layer.add(arc);
}

// 圆
function CIRCLE(val) {
  const group = new Konva.Group({
    name: 'station',
    x: val.x,
    y: val.y
  })
  const circle = new Konva.Rect({
    width: lineWidth * 20,
    height: lineWidth * 10,
    fill: stationType.get(val.type || 0),
    cornerRadius: lineWidth * 4,
    offset:{
      x:(lineWidth*20)/2,
      y:(lineWidth*10)/2,
    }
  });
  const text = new Konva.Text({
    text: val.stationname,
    fontSize: lineWidth * 12,
    fontFamily: 'KaiTi',
    fill: 'yellow',
    scaleY: -1,
    name: 'text'
  });
  text.offsetX(text.width() / 2)
  text.offsetY(text.height() / 2)

  group.add(circle).add(text);
  layer.add(group)
}

// 滚动缩放
function mousewheel() {
  stage.on('wheel', e => {
    e.evt.preventDefault();
    var oldScale = stage.scaleX();
    // console.log(stage.getPointerPosition(),stage.x(),stage.y())
    var mousePointTo = {
      x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
      y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale
    };

    var newScale = e.evt.deltaY < 0 ? oldScale * scale : oldScale / scale;
    // 如果比初始比例小则不能再缩小
    // if (newScale < initial.scale) newScale = initial.scale

    stage.scale({ x: newScale, y: -newScale });

    var newPos = {
      x: -(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale,
      y: -(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale
    };

    wheelScale = newScale
    stage.position(newPos);
  });
}